use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use tauri::Manager;

use crate::{ProxyConfig, system_proxy::SystemProxyConfig};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PresetConfig {
    pub name: String,
    pub description: String,
    pub config: ProxyConfig,
    pub is_builtin: bool,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AppConfig {
    pub proxy_configs: Vec<ProxyConfig>,
    pub current_proxy_index: Option<usize>,
    pub system_proxy_config: SystemProxyConfig,
    pub auto_start: bool,
    pub minimize_to_tray: bool,
    pub last_used_proxy: Option<ProxyConfig>,
    pub preset_configs: Vec<PresetConfig>,
}

impl Default for AppConfig {
    fn default() -> Self {
        Self {
            proxy_configs: Vec::new(),
            current_proxy_index: None,
            system_proxy_config: SystemProxyConfig::default(),
            auto_start: false,
            minimize_to_tray: true,
            last_used_proxy: None,
            preset_configs: get_builtin_presets(),
        }
    }
}

// 获取内置预设配置
fn get_builtin_presets() -> Vec<PresetConfig> {
    vec![
        PresetConfig {
            name: "本地HTTP代理".to_string(),
            description: "本地HTTP代理服务器 (127.0.0.1:8080)".to_string(),
            config: ProxyConfig {
                host: "127.0.0.1".to_string(),
                port: 8080,
                username: None,
                password: None,
                proxy_type: "http".to_string(),
                chain: None,
                load_balance_servers: None,
                load_balance_strategy: None,
                enable_tls: None,
                tls_verify_cert: None,
                dns_leak_protection: None,
                custom_dns_servers: None,
            },
            is_builtin: true,
        },
        PresetConfig {
            name: "本地SOCKS5代理".to_string(),
            description: "本地SOCKS5代理服务器 (127.0.0.1:1080)".to_string(),
            config: ProxyConfig {
                host: "127.0.0.1".to_string(),
                port: 1080,
                username: None,
                password: None,
                proxy_type: "socks5".to_string(),
                chain: None,
                load_balance_servers: None,
                load_balance_strategy: None,
                enable_tls: None,
                tls_verify_cert: None,
                dns_leak_protection: None,
                custom_dns_servers: None,
            },
            is_builtin: true,
        },
        PresetConfig {
            name: "Shadowsocks默认".to_string(),
            description: "Shadowsocks默认配置 (127.0.0.1:1080)".to_string(),
            config: ProxyConfig {
                host: "127.0.0.1".to_string(),
                port: 1080,
                username: None,
                password: None,
                proxy_type: "socks5".to_string(),
                chain: None,
                load_balance_servers: None,
                load_balance_strategy: None,
                enable_tls: None,
                tls_verify_cert: None,
                dns_leak_protection: None,
                custom_dns_servers: None,
            },
            is_builtin: true,
        },
    ]
}

// 获取配置文件路径
fn get_config_path(app_handle: &tauri::AppHandle) -> Result<PathBuf> {
    let app_data_dir = app_handle
        .path()
        .app_data_dir()
        .map_err(|e| anyhow::anyhow!("获取应用数据目录失败: {}", e))?;
    
    // 确保目录存在
    std::fs::create_dir_all(&app_data_dir)
        .map_err(|e| anyhow::anyhow!("创建应用数据目录失败: {}", e))?;
    
    Ok(app_data_dir.join("config.json"))
}

// 保存配置到文件
pub async fn save_config(app_handle: &tauri::AppHandle, config: &AppConfig) -> Result<()> {
    let config_path = get_config_path(app_handle)?;
    let config_json = serde_json::to_string_pretty(config)
        .map_err(|e| anyhow::anyhow!("序列化配置失败: {}", e))?;
    
    std::fs::write(&config_path, config_json)
        .map_err(|e| anyhow::anyhow!("写入配置文件失败: {}", e))?;
    
    tracing::info!("配置已保存到: {:?}", config_path);
    Ok(())
}

// 从文件加载配置
pub async fn load_config(app_handle: &tauri::AppHandle) -> Result<AppConfig> {
    let config_path = get_config_path(app_handle)?;
    
    if !config_path.exists() {
        tracing::info!("配置文件不存在，使用默认配置");
        return Ok(AppConfig::default());
    }
    
    let config_content = std::fs::read_to_string(&config_path)
        .map_err(|e| anyhow::anyhow!("读取配置文件失败: {}", e))?;
    
    let config: AppConfig = serde_json::from_str(&config_content)
        .map_err(|e| anyhow::anyhow!("解析配置文件失败: {}", e))?;
    
    tracing::info!("配置已从文件加载: {:?}", config_path);
    Ok(config)
}

// 保存代理配置
#[tauri::command]
pub async fn save_proxy_config(
    app_handle: tauri::AppHandle,
    config: ProxyConfig,
) -> Result<String, String> {
    let mut app_config = load_config(&app_handle)
        .await
        .map_err(|e| format!("加载配置失败: {}", e))?;
    
    // 检查是否已存在相同配置
    let existing_index = app_config.proxy_configs.iter().position(|c| {
        c.host == config.host && c.port == config.port && c.proxy_type == config.proxy_type
    });
    
    if let Some(index) = existing_index {
        // 更新现有配置
        app_config.proxy_configs[index] = config.clone();
        app_config.current_proxy_index = Some(index);
    } else {
        // 添加新配置
        app_config.proxy_configs.push(config.clone());
        app_config.current_proxy_index = Some(app_config.proxy_configs.len() - 1);
    }
    
    app_config.last_used_proxy = Some(config);
    
    save_config(&app_handle, &app_config)
        .await
        .map_err(|e| format!("保存配置失败: {}", e))?;
    
    Ok("代理配置已保存".to_string())
}

// 加载代理配置列表
#[tauri::command]
pub async fn load_proxy_configs(app_handle: tauri::AppHandle) -> Result<Vec<ProxyConfig>, String> {
    let app_config = load_config(&app_handle)
        .await
        .map_err(|e| format!("加载配置失败: {}", e))?;
    
    Ok(app_config.proxy_configs)
}

// 删除代理配置
#[tauri::command]
pub async fn delete_proxy_config(
    app_handle: tauri::AppHandle,
    index: usize,
) -> Result<String, String> {
    let mut app_config = load_config(&app_handle)
        .await
        .map_err(|e| format!("加载配置失败: {}", e))?;
    
    if index >= app_config.proxy_configs.len() {
        return Err("配置索引无效".to_string());
    }
    
    app_config.proxy_configs.remove(index);
    
    // 更新当前选中的索引
    if let Some(current_index) = app_config.current_proxy_index {
        if current_index == index {
            app_config.current_proxy_index = None;
        } else if current_index > index {
            app_config.current_proxy_index = Some(current_index - 1);
        }
    }
    
    save_config(&app_handle, &app_config)
        .await
        .map_err(|e| format!("保存配置失败: {}", e))?;
    
    Ok("代理配置已删除".to_string())
}

// 获取最后使用的代理配置
#[tauri::command]
pub async fn get_last_used_proxy(app_handle: tauri::AppHandle) -> Result<Option<ProxyConfig>, String> {
    let app_config = load_config(&app_handle)
        .await
        .map_err(|e| format!("加载配置失败: {}", e))?;
    
    Ok(app_config.last_used_proxy)
}

// 保存应用设置
#[tauri::command]
pub async fn save_app_settings(
    app_handle: tauri::AppHandle,
    auto_start: bool,
    minimize_to_tray: bool,
) -> Result<String, String> {
    let mut app_config = load_config(&app_handle)
        .await
        .map_err(|e| format!("加载配置失败: {}", e))?;
    
    app_config.auto_start = auto_start;
    app_config.minimize_to_tray = minimize_to_tray;
    
    save_config(&app_handle, &app_config)
        .await
        .map_err(|e| format!("保存配置失败: {}", e))?;
    
    Ok("应用设置已保存".to_string())
}

// 获取应用设置
#[tauri::command]
pub async fn get_app_settings(app_handle: tauri::AppHandle) -> Result<(bool, bool), String> {
    let app_config = load_config(&app_handle)
        .await
        .map_err(|e| format!("加载配置失败: {}", e))?;

    Ok((app_config.auto_start, app_config.minimize_to_tray))
}

// 获取预设配置列表
#[tauri::command]
pub async fn get_preset_configs(app_handle: tauri::AppHandle) -> Result<Vec<PresetConfig>, String> {
    let app_config = load_config(&app_handle)
        .await
        .map_err(|e| format!("加载配置失败: {}", e))?;

    Ok(app_config.preset_configs)
}

// 添加自定义预设配置
#[tauri::command]
pub async fn add_preset_config(
    app_handle: tauri::AppHandle,
    name: String,
    description: String,
    config: ProxyConfig,
) -> Result<String, String> {
    let mut app_config = load_config(&app_handle)
        .await
        .map_err(|e| format!("加载配置失败: {}", e))?;

    let preset = PresetConfig {
        name,
        description,
        config,
        is_builtin: false,
    };

    app_config.preset_configs.push(preset);

    save_config(&app_handle, &app_config)
        .await
        .map_err(|e| format!("保存配置失败: {}", e))?;

    Ok("预设配置已添加".to_string())
}

// 删除自定义预设配置
#[tauri::command]
pub async fn delete_preset_config(
    app_handle: tauri::AppHandle,
    index: usize,
) -> Result<String, String> {
    let mut app_config = load_config(&app_handle)
        .await
        .map_err(|e| format!("加载配置失败: {}", e))?;

    if index >= app_config.preset_configs.len() {
        return Err("预设配置索引无效".to_string());
    }

    if app_config.preset_configs[index].is_builtin {
        return Err("不能删除内置预设配置".to_string());
    }

    app_config.preset_configs.remove(index);

    save_config(&app_handle, &app_config)
        .await
        .map_err(|e| format!("保存配置失败: {}", e))?;

    Ok("预设配置已删除".to_string())
}
